package com.github.mzule.fantasyslide;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.render.*;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

/**
 * 背景视图,根据设定的 color 以及 y 位移绘制曲线背景。
 * Created by CaoDongping on 9/6/16.
 */
class SideBarBgView extends Component implements Component.DrawTask {
    private Paint paint;
    private Path path;
    private LayoutDirection parentLayoutGravity;
    private boolean drawableProcessed;
    private Element drawable;

    public SideBarBgView(Context context) {
        this(context, null);
        init();
    }

    public SideBarBgView(Context context, AttrSet attrSet) {
        super(context, attrSet);
        init();
        addDrawTask(this::onDraw);
    }

    public SideBarBgView(Context context, AttrSet attrSet, int resId) {
        super(context, attrSet, resId);
        init();
        addDrawTask(this::onDraw);
    }


    private void init() {
        paint = new Paint();
        paint.setAntiAlias(true);
        path = new Path();
    }

    void setParentLayoutGravity(LayoutDirection parentLayoutGravity) {
        this.parentLayoutGravity = parentLayoutGravity;
    }

    public void setTouchY(float y, float percent, boolean isLeft) {
        path.reset();
        float width = getWidth() * percent;
        float height = getHeight();
        float arcWidth = width / 2; // 宽度的一般作为贝瑟尔曲线宽度
        float yOffset = height / 8; // 贝塞尔曲线高度的 offset,以达到背景的上下宽度变化
        if (isLeft) {
            path.lineTo(width - arcWidth, -yOffset);
            path.quadTo(width + arcWidth, y, width - arcWidth, height + yOffset);
            path.lineTo(0, height);
            path.close();
            path.offset(getWidth() - width, 0);
        } else {
            path.moveTo(arcWidth, -yOffset);
            path.lineTo(width, 0);
            path.lineTo(width, height);
            path.lineTo(arcWidth, height + yOffset);
            path.quadTo(-arcWidth, y, arcWidth, -yOffset);
            path.close();
        }
        invalidate();
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (drawable != null && !drawableProcessed) {
            drawableProcessed = true;
            paint.setShader(createShader(), Paint.ShaderType.GROUP_SHADER);
        }
        paint.setStyle(Paint.Style.FILL_STYLE);
        canvas.drawPath(path, paint);
    }

    private Shader createShader() {
        PixelMap bitmap;
        if (drawable instanceof PixelMapElement) {
            bitmap = ((PixelMapElement) drawable).getPixelMap();
        } else {
            PixelMap.InitializationOptions initializationOptions =
                    new PixelMap.InitializationOptions();
            initializationOptions.pixelFormat = PixelFormat.ARGB_8888;
            initializationOptions.size = new Size(getWidth(), getHeight());
            bitmap = PixelMap.create(initializationOptions);
            Texture texture = new Texture(bitmap);
            Canvas c = new Canvas(texture);
            drawable.setBounds(0, 0, getWidth(), getHeight());
            drawable.drawToCanvas(c);
        }
        PixelMapHolder pixelMapHolder = new PixelMapHolder(bitmap);
        return new PixelMapShader(pixelMapHolder,
                Shader.TileMode.REPEAT_TILEMODE, Shader.TileMode.REPEAT_TILEMODE);
    }

    public void setDrawable(Element drawable) {
//        if (drawable instanceof ColorDrawable) {
//            paint.setColor(((ColorDrawable) drawable).getColor());
//        } else {
//            this.drawable = drawable;
//            this.drawableProcessed = false;
//        }
        this.drawable = drawable;
        paint.setColorMatrix(drawable.getColorMatrix());
    }
}
